package com.yanfan.modbus.frame;

import com.yanfan.common.ByteUtil;
import com.yanfan.modbus.ModbusUtils;
import com.yanfan.modbus.code.FunctionCode;
import com.yanfan.modbus.exception.ModbusTransportException;
import com.yanfan.modbus.frame.abs.ModbusRequest;
import io.netty.buffer.ByteBuf;


public class WriteRegistersRequest extends ModbusRequest {
    private int startOffset;
    private byte[] data;


    public WriteRegistersRequest(int slaveId, int startOffset, short[] sdata) throws ModbusTransportException {
        super(slaveId);
        this.startOffset = startOffset;
        data = ByteUtil.convertToBytes(sdata);
    }


    public WriteRegistersRequest(int slaveId) throws ModbusTransportException {
        super(slaveId);
    }

    @Override
    public void validate() throws ModbusTransportException {
        ModbusUtils.validateOffset(startOffset);
        int registerCount = data.length / 2;
        if (registerCount < 1 || registerCount > ModbusUtils.DEFAULT_MAX_WRITE_REGISTER_COUNT) {
            throw new ModbusTransportException("Invalid number of registers: " + registerCount, slaveId);
        }
        ModbusUtils.validateEndOffset(startOffset + registerCount - 1);
    }

    @Override
    public byte getFunctionCode() {
        return FunctionCode.WRITE_REGISTERS;
    }


    @Override
    protected void writeRequest(ByteBuf buf) {
        buf.writeShort(startOffset);
        buf.writeShort(data.length / 2);
        buf.writeByte(data.length);
        buf.writeBytes(data);
    }


    @Override
    protected void readRequest(ByteBuf buf) {
        startOffset = buf.readUnsignedShort();
        buf.readUnsignedShort(); // register count not needed.
        data = new byte[buf.readUnsignedByte()];
        buf.readBytes(data);
    }
}
